iT邦幫忙

2022 iThome 鐵人賽

DAY 19
0

任何以 Ruby 寫的框架,都可以透過 Rack 中介軟體來修改他的運作方式

Rack 是以一層層的方式建構你的框架及應用程式

Care and Feeding of Config.ru

用 Rack 做出來的應用程式,會有 config.ru 檔,是一種 RackUp 檔案

Rack 使用 call() 來呼叫 Endpoints

就像呼叫 Proc 一樣

# sample_dir/config.ru
run proc {
  [200, {'Content-Type' => 'text/html'}, ["Hello, world!"]]
}

這段程式碼會回傳 HTTP 狀態、header 跟 body

使用 rackup -p 3001 或 bundle exec rackup -p 3001 跑

會開啟 3001 的 port

然後你會看到 Hello, world!

你可以用 call 方法去指定一個 endpoint 物件

endpoint
endpoint 會告訴 API 該走哪個路徑,請它去找相對應的 controller 及 action

# sample_dir/config.ru
  obj = Object.new
  def obj.call(*args)
    [200, {'Content-Type' => 'text/html'}, ["Hello, world!"]]
  end
  run obj

接下來,我們來看看 Rack 該怎麼運作

# sample_dir/config.ru
  INNER_LAYER = proc { "world!" }
  OUTER_LAYER = proc {
    inner_content = INNER_LAYER.call
    [
      200, 
      {'Content-Type' => 'text/html'},
      ["Hello," + inner_content]
    ]
  }
  run OUTER_LAYER

內層只返回一個 world
外層把內層包起來,然後把 Hello 印出來

這是 Rack 的運作方式

每一層修改過後
內層返回一個結果

The Real Thing

Rack 並不知道該怎麼找下一層

要找下一層就必須要寫一個可以重複使用的程式碼

相反的, Rack 會傳送每一層當作下一層初始化參數

我們要用 use 來做些設定

# sample_dir/config.ru
  use Rack::Auth::Basic, "app" do |_, pass|
    'secret' == pass
  end
  run proc {
    [200, {'Content-Type' => 'text/html'}, ["Hello, world!"]]
  }

拿到一個 username 以及 password

呼叫任何你想要的 user 資訊

你需要兩層的 Rack app

當我們使用 use 時,我們要跟他說要產生什麼 class 以及 傳什麼參數進去

現在我們在 config.ru 設定一下 middleware class

# sample_dir/config.ru
  class Canadianize
    def initialize(app, arg = "")
      @app = app
      @arg = arg
    end
    
    def call(env)
      status, headers, content = @app.call(env)
      content[0] += @arg + ", eh?"
      [ status, headers, content ]
    end 
  end
  use Canadianize, ", simple"
  run proc {
    [200, {'Content-Type' => 'text/html'}, ["Hello world"]]
  }

因為傳送了 simple 參數給 Canadianize 的初始化

所以最後會顯示在畫面上的是 Hello world , simple

這個 block 傳送給 Rack::Auth::Basic 裡的 initialize 方法

就像參數被傳進 Canadianize 中

你可以依照需求傳參數數量進去

但是 initialize() 的參數需要跟 use() 的參數一樣

# best_quotes/config.ru
  require "./config/application"
  run BestQuotes::Application.new

BestQuotes::Application 有 call 方法

所以你可以用 run 來呼叫他們

最後回傳的結果會顯示在瀏覽器上


上一篇
Day 18 - ORM
下一篇
Day 20 - Rack Middleware
系列文
從0開始刻 淺談 Rails 的運作魔法30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言